package cn.eeepay.boss.action;

import cn.eeepay.boss.system.DataSource;
import cn.eeepay.boss.system.SystemLog;
import cn.eeepay.framework.db.pagination.Page;
import cn.eeepay.framework.model.*;
import cn.eeepay.framework.service.*;
import cn.eeepay.framework.service.impl.PosCardBinServiceImpl;
import cn.eeepay.framework.util.Constants;
import cn.eeepay.framework.util.ListDataExcelExport;
import cn.eeepay.framework.util.ResponseUtil;
import cn.eeepay.framework.util.StringUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 
 * @author tans
 * @date 2017年3月14日 下午3:23:10
 */
@Controller
@RequestMapping(value="/jumpRoute")
public class JumpRouteAction {

	public static final String ACQ="ACQ_MERCHANT_TYPE";//收单商户类别 数据字典key值

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Resource
	private JumpRouteService jumpRouteSevice;
	
	@Resource
	private MerchantInfoService merchantInfoService;
	
	@Resource
	private PosCardBinServiceImpl posCardBinService;
	
   	@Resource
	private SysDictService sysDictService;

	@Resource
	private SysWarningService sysWarningService;

	@Resource
	private AccountAddressService accountAddressService;
	@Resource
	private AreaInfoService areaInfoService;
	@Resource
	private AddressMappingService addressMappingService;
	@Resource
	private JumpWarnService jumpWarnService;
	@Resource
	private JumpRouteQuotaLogService jumpRouteQuotaLogService;
	@Resource
	private WarningConfigTemplateService warningConfigTemplateService;

	/**
	 * 
	 * @author tans
	 * @date 2017年3月14日 下午3:27:14
	 * @return
	 */
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping(value="/page.do")
	@ResponseBody
	public Page<JumpRouteConfig> list(@RequestParam("baseInfo") String param, 
			@ModelAttribute("page") Page<JumpRouteConfig> page){
		logger.info("入参：" + JSONObject.toJSONString(param));
		try {
			JumpRouteConfig baseInfo = JSONObject.parseObject(param, JumpRouteConfig.class);
			jumpRouteSevice.list(baseInfo, page);
		} catch (Exception e) {
			logger.error("条件查询跳转集群配置列表失败",e);
		}
		return page;
	}
	
	/**
	 * 保存交易跳转集群配置
	 * @author tans
	 * @date 2017年3月15日 上午11:52:24
	 * @param params
	 * @return
	 */
	@RequestMapping(value="/save.do")
	@ResponseBody
	@SystemLog(description = "保存",operCode="jumpRoute.save")
	public Result save(@RequestBody String params){
		Result result = Result.fail();
		try {
			int num = jumpRouteSevice.save(params);
			if(num == 1){
				result = Result.success();
			}
		} catch (Exception e) {
			logger.error("保存交易跳转集群配置失败", e);
			result = ResponseUtil.buildResult(e);
		}
		return result;
	}
	
	/**
	 * 修改交易跳转集群的配置
	 * @author tans
	 * @date 2017年3月15日 下午4:49:28
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/update/{id}")
	@ResponseBody
	public Map<String, Object> update(@PathVariable("id") Integer id){
		Map<String, Object> msg = new HashMap<>();
		msg.put("status", false);
		try {
			JumpRouteConfig baseInfo = jumpRouteSevice.getById(id);
			msg.put("status", true);
			msg.put("baseInfo", baseInfo);
		} catch (Exception e) {
			logger.error("保存交易跳转集群配置失败", e);
		}
		return msg;
	}
	
	/**
	 * 删除交易跳转集群的配置
	 * @author tans
	 * @date 2017年3月16日 下午3:05:36
	 * @param
	 * @return
	 */
	@RequestMapping(value="/delete.do")
	@ResponseBody
	@SystemLog(description = "删除交易跳转集群配置",operCode="jumpRoute.delete")
	public Map<String, Object> delete(@RequestParam("id") String id){
		Map<String, Object> msg = new HashMap<>();
		msg.put("status", false);
		msg.put("msg", "删除失败");
		try {
			int num = jumpRouteSevice.delete(id);
			if(num>0){
				msg.put("status", true);
				msg.put("msg", "删除成功");
			}
		} catch (Exception e) {
			logger.error("删除交易跳转集群的配置失败", e);
		}
		return msg;
	}
	
	/**** 交易跳转集群白名单管理  ******/
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping(value="/selectAllWlInfo")
	@ResponseBody
	public Map<String, Object> selectAllWlInfo(){
		Map<String, Object> msg = new HashMap<>();
		msg.put("status", false);
		try {
			List<AcpWhitelist> result = jumpRouteSevice.selectAllWlInfo();
			msg.put("status", true);
			msg.put("result", result);
		} catch (Exception e) {
			logger.error("查询交易跳转集群配置商户白名单失败", e);
		}
		return msg;
	}
	
	@RequestMapping(value = "/deleteWlInfo")
	@ResponseBody
	@SystemLog(description = "交易跳转集群白名单删除",operCode="jumpRoute.deleteWhite")
	public Object deleteWlInfo(@RequestParam("ids") String param) {
		Map<String, Object> jsonMap = new HashMap<String, Object>();
		try {
			int id = JSON.parseObject(param, Integer.class);
			int i = jumpRouteSevice.deleteByWlid(id);
			if (i > 0) {
				jsonMap.put("msg", "删除成功");
				jsonMap.put("status", true);
			} else {
				jsonMap.put("msg", "删除失败");
				jsonMap.put("status", false);
			}
		} catch (Exception e) {
			logger.error("交易跳转集群白名单删除报错", e);
			jsonMap.put("msg", "交易跳转集群白名单删除报错");
			jsonMap.put("status", false);
		}
		return jsonMap;
	}
	
	/**
	 * 收单机构白名单新增
	 * 
	 * @param
	 * @return
	 */
	@RequestMapping(value = "/addWlInfo")
	@ResponseBody
	@SystemLog(description = "交易跳转集群白名单新增",operCode="jumpRoute.insertWhite")
	public Object addWlInfo(@RequestParam("info") String merchantNo) {
		Map<String, Object> jsonMap = new HashMap<String, Object>();
		try {
			final UserLoginInfo principal = (UserLoginInfo) SecurityContextHolder.getContext().getAuthentication()
					.getPrincipal();
			AcpWhitelist aw = new AcpWhitelist();
			aw.setMerchantNo(merchantNo);
			if (merchantInfoService.selectByMerNo(merchantNo) == null) {
				jsonMap.put("msg", "商户编号不正确");
				jsonMap.put("status", false);
				return jsonMap;
			}
			AcpWhitelist dataAl = jumpRouteSevice.getWlInfoByMerchantNo(merchantNo);
			if(dataAl != null){
				jsonMap.put("msg", "商户编号已存在");
				jsonMap.put("status", false);
				return jsonMap;
			}
			
			aw.setCreatePerson(principal.getRealName());
			int i = jumpRouteSevice.insertWl(aw);
			if (i > 0) {
				jsonMap.put("msg", "新增成功");
				jsonMap.put("status", true);
			} else {
				jsonMap.put("msg", "新增失败");
				jsonMap.put("status", false);
			}
		} catch (Exception e) {
			logger.error("交易跳转集群白名单新增报错~~~~~", e);
			jsonMap.put("msg", "交易跳转集群白名单新增报错~~~~~");
			jsonMap.put("bols", false);
		}
		return jsonMap;
	}

	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping(value = "/getCarBinList")
	@ResponseBody
	public List<Map<String,Object>> getCarBinList(@RequestParam("cardType") int cardType) {
		return posCardBinService.getCarBinList(cardType);
	}
	
	/**** 交易跳转集群白名单管理  ******/


	/**
	 * 获取收单商户类别
	 * @return
	 */
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping(value = "/getSysDictList")
	@ResponseBody
	public List<SysDict> getSysDictList(){
		return sysDictService.getAcqMerchantList(JumpRouteAction.ACQ);
	}
	
	
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@ResponseBody
	@RequestMapping("/getServiceTypeSelect")
	public List<SysDict> getServiceTypeSelect(String bqIds){
		Integer[] ids = JSONObject.parseObject(bqIds,Integer[].class);
		return jumpRouteSevice.getServiceTypeSelectByBqIds(ids);
	}

	/**
	 * 目标金额预警
	 * @return
	 */
	@RequestMapping(value = "/selectTargetAmountWarning")
	@ResponseBody
	public Object selectTargetAmountWarning() {
		Map<String, Object> maps = new HashMap<>();
		try {
			maps.put("yesAmountWarning", sysWarningService.getByType("3"));
			maps.put("noAmountWarning", sysWarningService.getByType("4"));
			maps.put("status", true);
		} catch (Exception e) {
			logger.error("目标金额预警查询报错", e);
			maps.put("msg", "目标金额预警查询报错");
			maps.put("status", false);
		}
		return maps;
	}


	/**
	 * 目标金额预警修改
	 * @return
	 */
	@RequestMapping(value = "/updateTargetAmountWarning")
	@ResponseBody
	@SystemLog(description = "目标金额预警修改", operCode = "jumpRoute.updateTargetAmountWarning")
	public Object updateTargetAmountWarning(@RequestBody String param) {
		Map<String, Object> maps = new HashMap<>();
		JSONObject json = JSON.parseObject(param);
		Map<String, Object> yesAmountWarning = json.getObject("yesAmountWarning", Map.class);
		Map<String, Object> noAmountWarning = json.getObject("noAmountWarning", Map.class);
		try {
			sysWarningService.updateSysWarning(yesAmountWarning);
			sysWarningService.updateSysWarning(noAmountWarning);
			maps.put("status", true);
		} catch (Exception e) {
			logger.error("目标金额预警修改报错", e);
			maps.put("msg", "目标金额预警修改报错");
			maps.put("status", false);
		}
		return maps;
	}

	/**
	 * 跳转路由集群导出
	 * @param baseInfo
	 * @param response
	 */
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping("/export")
	@SystemLog(operCode = "jumpRoute.export", description = "导出")
	public void export(String baseInfo, HttpServletResponse response){
		try {
			if(StringUtils.isNotEmpty(baseInfo)){
				baseInfo = URLDecoder.decode(baseInfo, "utf-8");
			}
			JumpRouteConfig config = JSONObject.parseObject(baseInfo, JumpRouteConfig.class);
			jumpRouteSevice.export(response, config);
		} catch (Exception e){
			logger.error("跳转路由集群导出异常", e);
		}
	}


	//路由监控查询
	@RequestMapping("/routeMonitor.do")
	@ResponseBody
	public Page<JumpRouteQuotaLog> routeMonitor(Integer jumpId,String dateStart,String dateEnd,Integer pageNo,Integer pageSize){
		try {
			Page<JumpRouteQuotaLog> page = new Page(pageNo,pageSize);
			String today = DateUtil.today();
			if(dateStart.equals(today) || dateEnd.equals(today)){
				jumpRouteQuotaLogService.routeMonitorLogPage(jumpId,today,page);
			}else{
				jumpRouteQuotaLogService.routeMonitorHistoryLogPage(jumpId,dateStart,dateEnd,page);
			}
			return page;
		} catch (Exception e) {
			logger.error("查询智能路由交易监控数据异常", e);
		}
		return null;
	}

	/**
	 * 	路由监控导出
	 */
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping("/routeMonitorExport.do")
	@SystemLog(operCode = "routeMonitor.export", description = "路由监控导出")
	public void routeMonitorExport(Integer jumpId,String dateStart,String dateEnd, HttpServletResponse response){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss") ;
			OutputStream ouputStream = null;
			try {
				Page<JumpRouteQuotaLog> page = new Page(0, Integer.MAX_VALUE);
				String today = DateUtil.today();
				if(dateStart.equals(today) || dateEnd.equals(today)){
					jumpRouteQuotaLogService.routeMonitorLogPage(jumpId,today,page);
				}else{
					jumpRouteQuotaLogService.routeMonitorHistoryLogPage(jumpId,dateStart,dateEnd,page);
				}
				List<JumpRouteQuotaLog> configList = page.getResult();
				int size = 2;
				ListDataExcelExport export = new ListDataExcelExport(size);
				String fileName = "路由监控" + sdf.format(new Date()) + export.getFileSuffix(size);
				String fileNameFormat = new String(fileName.getBytes(),"ISO-8859-1");
				response.setHeader("Content-disposition", "attachment;filename="+fileNameFormat);
				response.setContentType("application/vnd.ms-excel;charset=utf-8");
				List<Map<String, String>> data = new ArrayList<>();

				for(JumpRouteQuotaLog item: configList){
					Map<String,String> map = new HashMap<>();
					map.put("jumpId", item.getJumpId().toString());
					map.put("remark", item.getRemark());
					map.put("targetQuota",item.getTargetQuota() == null ? BigDecimal.ZERO.toString() : item.getTargetQuota().toString());
					map.put("transAmount",item.getTransAmount() == null ? BigDecimal.ZERO.toString() : item.getTransAmount().toString());
					map.put("accountDate",DateUtil.formatDate(item.getAccountDate()));
					data.add(map);
				}
				String[] cols = new String[]{
						"jumpId","remark","targetQuota","transAmount","accountDate"
				};
				String[] colsName = new String[]{
						"路由id","备注","目标金额","已跑量金额","日期"
				};
				ouputStream = response.getOutputStream();
				export.export(cols, colsName, data, response.getOutputStream());
			} catch (Exception e) {
				logger.error("跳转路由集群导出异常", e);
			} finally {
				if(ouputStream!=null){
					try {
						ouputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Exception e){
			logger.error("路由监控导出异常", e);
		}
	}

	//注册地监控
	@RequestMapping("/addressMonitor.do")
	@ResponseBody
	public Map<String,Object> addressMonitor(String address,String dateStart,String dateEnd,Integer pageNo,Integer pageSize){
		Map<String,Object> result = new HashMap<>();
		try {
			Page<AccountAddrOrder> page = new Page(pageNo, pageSize);
			Map<String,Object> accountAddrOrders = accountAddressService.addressMonitor(address, dateStart, dateEnd,page);
			result.put("data",accountAddrOrders);
			result.put("totalCount",page.getTotalCount());
			result.put("status",true);
		} catch (Exception e) {
			logger.error("注册地监控数据查询异常", e);
			result.put("status",false);
			result.put("msg","注册地监控数据查询失败");
		}
		return result;
	}

	//注册地监控详情
	@RequestMapping("/addressMonitorDetail.do")
	@ResponseBody
	public Object addressMonitorDetail(String address,String date){
		Result result = Result.fail();
		try {
			List<AccountAddrOrder> accountAddressList = accountAddressService.addressMonitorDetail(address, date);
			result = Result.success(null,accountAddressList);
		} catch (Exception e) {
			logger.error("注册地监控详情异常", e);
		}
		return result;
	}


	//注册地监控详情
	@SystemLog(description="注册地监控详情",operCode = "")
	@RequestMapping("/addressMonitorDetailExport.do")
	public void addressMonitorDetailExport(String address,String date, HttpServletResponse response){
		OutputStream ouputStream = null;
		try {
			List<AccountAddrOrder> accountAddressList = accountAddressService.addressMonitorDetail(address, date);
			int size = 2;
			ListDataExcelExport export = new ListDataExcelExport(size);
			String fileName = "注册地交易分布("+address+date+")" + export.getFileSuffix(size);
			String fileNameFormat = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
			response.setHeader("Content-disposition", "attachment;filename=" + fileNameFormat);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");

			List<Map<String,String>> list = new ArrayList<>();

			if(CollectionUtil.isNotEmpty(accountAddressList)){
				for (AccountAddrOrder accountAddrOrder : accountAddressList) {
					Map<String,String> map = new HashMap<>();
					map.put("accountAddress",accountAddrOrder.getAccountAddress());
					map.put("transAmount",accountAddrOrder.getTransAmount().toString());
					map.put("accountDate",DateUtil.formatDate(accountAddrOrder.getAccountDate()));
					list.add(map);
				}
			}

			String[] cols = new String[]{
					"accountAddress","transAmount","accountDate"
			};
			String[] colsName = new String[]{
					"账单地","已跑量金额(元)","日期"
			};

			ouputStream = response.getOutputStream();

			export.export(cols, colsName, list, response.getOutputStream());
		} catch (Exception e) {
			logger.error("注册地监控详情导出异常", e);
		} finally {
			try {
				if (ouputStream != null) {
					ouputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 	注册地监控导出
	 */
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping("/regAddressMonitorExport.do")
	@SystemLog(operCode = "regAddressMonitor.export", description = "注册地监控导出")
	public void regAddressMonitorExport(String address,String dateStart,String dateEnd, HttpServletResponse response){
		OutputStream ouputStream = null;
		try {
			Page<AccountAddrOrder> page = new Page(0, Integer.MAX_VALUE);
			Map<String,Object> exportMap = accountAddressService.addressMonitorExport(address, dateStart,dateEnd,page);
			int size = 2;
			ListDataExcelExport export = new ListDataExcelExport(size);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
			String fileName = "注册地监控("+address+")" + sdf.format(new Date()) + export.getFileSuffix(size);
			String fileNameFormat = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
			response.setHeader("Content-disposition", "attachment;filename=" + fileNameFormat);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");

			List<Map<String,String>> data = (List<Map<String, String>>) exportMap.get("data");
			List<String> cols  = (List<String>) exportMap.get("cols");
			List<String> colsName  = (List<String>) exportMap.get("colsName");

			String[] colsArr = cols.toArray(new String[cols.size()]);
			String[] colsNameArr = colsName.toArray(new String[colsName.size()]);

			ouputStream = response.getOutputStream();

			export.export(colsArr, colsNameArr, data, response.getOutputStream());
		} catch (Exception e) {
			logger.error("注册地监控导出异常", e);
		} finally {
			try {
				if (ouputStream != null) {
					ouputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


	//账单地监控
	@RequestMapping("/accountAddressMonitor.do")
	@ResponseBody
	public Map<String,Object> accountAddressMonitor(String address,String dateStart,String dateEnd,Integer pageNo,Integer pageSize){
		Map<String,Object> result = new HashMap<>();
		try {
			Page<AccountAddrOrder> page = new Page(pageNo, pageSize);
			Map<String,Object> accountAddrOrders = accountAddressService.accountAddressMonitor(address, dateStart, dateEnd,page);
			result.put("data",accountAddrOrders);
			result.put("totalCount",page.getTotalCount());
			result.put("status",true);
		} catch (Exception e) {
			logger.error("账单地监控数据查询异常", e);
			result.put("status",false);
			result.put("msg","账单地监控数据查询失败");
		}
		return result;
	}


	//账单地监控详情
	@RequestMapping("/accountAddressMonitorDetail.do")
	@ResponseBody
	public Object accountAddressMonitorDetail(String address,String date){
		Result result = Result.fail();
		try {
			List<AccountAddrOrder> accountAddressList = accountAddressService.accountAddressMonitorDetail(address, date);
			result = Result.success(null,accountAddressList);
		} catch (Exception e) {
			logger.error("账单地监控详情异常", e);
		}
		return result;
	}

	//账单地监控详情
	@SystemLog(description="账单地监控详情",operCode = "")
	@RequestMapping("/accountAddressMonitorDetailExport.do")
	public void accountAddressMonitorDetailExport(String address,String date, HttpServletResponse response){
		OutputStream ouputStream = null;
		try {
			List<AccountAddrOrder> accountAddressList = accountAddressService.accountAddressMonitorDetail(address, date);
			int size = 2;
			ListDataExcelExport export = new ListDataExcelExport(size);
			String fileName = "账单地交易分布("+address+date+")" + export.getFileSuffix(size);
			String fileNameFormat = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
			response.setHeader("Content-disposition", "attachment;filename=" + fileNameFormat);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");

			List<Map<String,String>> list = new ArrayList<>();

			if(CollectionUtil.isNotEmpty(accountAddressList)){
				for (AccountAddrOrder accountAddrOrder : accountAddressList) {
					Map<String,String> map = new HashMap<>();
					map.put("merProvince",accountAddrOrder.getMerProvince());
					map.put("transAmount",accountAddrOrder.getTransAmount().toString());
					map.put("accountDate",DateUtil.formatDate(accountAddrOrder.getAccountDate()));
					list.add(map);
				}
			}

			String[] cols = new String[]{
					"merProvince","transAmount","accountDate"
			};
			String[] colsName = new String[]{
					"注册地","已跑量金额(元)","日期"
			};

			ouputStream = response.getOutputStream();

			export.export(cols, colsName, list, response.getOutputStream());
		} catch (Exception e) {
			logger.error("账单地监控详情导出异常", e);
		} finally {
			try {
				if (ouputStream != null) {
					ouputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


	/**
	 * 	账单地监控导出
	 */
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping("/accountAddressMonitorExport.do")
	@SystemLog(operCode = "accountAddressMonitor.export", description = "账单地监控导出")
	public void accountAddressMonitorExport(String address,String dateStart,String dateEnd, HttpServletResponse response){
		OutputStream ouputStream = null;
		try{
			Page<AccountAddrOrder> page = new Page(0, Integer.MAX_VALUE);
			Map<String,Object> exportMap = accountAddressService.accountAddressMonitorExport(address, dateStart, dateEnd,page);
			int size = 2;
			ListDataExcelExport export = new ListDataExcelExport(size);
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
			String fileName = "账单地监控("+address+")" + sdf.format(new Date()) + export.getFileSuffix(size);
			String fileNameFormat = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
			response.setHeader("Content-disposition", "attachment;filename=" + fileNameFormat);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");

			List<Map<String,String>> data = (List<Map<String, String>>) exportMap.get("data");
			List<String> cols  = (List<String>) exportMap.get("cols");
			List<String> colsName  = (List<String>) exportMap.get("colsName");

			String[] colsArr = cols.toArray(new String[cols.size()]);
			String[] colsNameArr = colsName.toArray(new String[colsName.size()]);

			ouputStream = response.getOutputStream();

			export.export(colsArr, colsNameArr, data, response.getOutputStream());
		} catch (Exception e) {
			logger.error("账单地监控导出异常", e);
		} finally {
			try {
				if (ouputStream != null) {
					ouputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 映射地区导入
	 *
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/addressMappingImport")
	@ResponseBody
	public Result addressMappingImport(@RequestParam("file") MultipartFile file) {
		Result result = new Result();
		logger.info("=====映射地区导入");
		String errorMessage = "模版错误，导入失败";
		try {
			Map<String, String> map = new HashMap<>();
			Workbook wb = WorkbookFactory.create(file.getInputStream());
			Sheet sheet = wb.getSheetAt(0);
			int row_num = sheet.getLastRowNum();
			List<AddressMapping> lists = new ArrayList<>();
			List<String> registerAddressList = new ArrayList<>();
			for (int i = 1; i <= row_num; i++) {
				AddressMapping am = new AddressMapping();
				Row row = sheet.getRow(i);
				short lastCellNum = row.getLastCellNum();		//总列数

				Cell cell0 = row.getCell(0);
				if (cell0 == null) {
					continue;
				}
				String registerAddress = cell0.getStringCellValue();			//商户注册地
				if (StringUtil.isEmpty(registerAddress)) {
					continue;
				}
				if(registerAddressList.contains(registerAddress)){
					errorMessage = String.format("注册地\"%s\"重复",registerAddress);
					result.setStatus(false);
					result.setMsg(errorMessage);
					return result;
				}else{
					registerAddressList.add(registerAddress);
				}

				Cell cell1 = row.getCell(1);
				if (cell1 == null) {
					continue;
				}
				String addressType = cell1.getStringCellValue();			//是否单列市
				if (StringUtil.isEmpty(addressType)) {
					continue;
				}

				int type = StrUtil.isNotEmpty(addressType) && addressType.equals("否") ? 0 : 1;
				am.setRegisterAddressType(type);			//是否单列市

				if(addressType.equals("是")){
					AreaInfo province = areaInfoService.getProvinceByCityName(registerAddress);
					if(province == null){
						errorMessage = String.format("商户注册地未找到市区\"%s\"，请确定市区名字是否正确",registerAddress);
						result.setStatus(false);
						result.setMsg(errorMessage);
						return result;
					}
					am.setRegisterAddressParent(province.getName());
					am.setRegisterAddress(registerAddress);
				}else{
					AreaInfo province = areaInfoService.getProvinceByName(registerAddress);
					if(province == null){
						errorMessage = String.format("商户注册地未找到省\"%s\"，请确定省名字是否正确",registerAddress);
						result.setStatus(false);
						result.setMsg(errorMessage);
						return result;
					}
					am.setRegisterAddressParent(registerAddress);
					am.setRegisterAddress(registerAddress);
				}

				Cell cell2 = row.getCell(2);
				String joinAreaPolling = cell2.getStringCellValue();        //不参与地区轮询		0:参与 1：不参与
				if (StringUtil.isEmpty(joinAreaPolling)) {
					continue;
				}
				int join = StrUtil.isNotEmpty(joinAreaPolling) && joinAreaPolling.equals("参与") ? 0 : 1;
				am.setJoinAreaPolling(join);

				int mappings = lastCellNum;		//剩余映射地区数量
				if((mappings - 3) % 2 != 0){
					result.setStatus(false);
					result.setMsg("导入失败，映射地区列数不正确");
					return result;
				}

				JSONArray jsonArray = new JSONArray();
				List<String> items = new ArrayList<>();
				int no = 0;
				List<String> regAddressList = new ArrayList<>();
				for (int x = 3; x < mappings; x = x+2) {
					Cell cellx1 = row.getCell(x);
					Cell cellx2 = row.getCell(x+1);
					if(cellx1 == null || cellx2 == null){
						continue;
					}
					String area = cellx1.getStringCellValue();
					if(StrUtil.isEmpty(area)){
						continue;
					}
					if(regAddressList.contains(area)){
						errorMessage = String.format("注册地\"%s\"不能重复添加映射地\"%s\"",registerAddress,area);
						result.setStatus(false);
						result.setMsg(errorMessage);
						return result;
					}else{
						regAddressList.add(area);
					}
					String only = cellx2.getStringCellValue();
					if(StrUtil.isEmpty(area) || StrUtil.isEmpty(only)){
						continue;
					}
					JSONObject jsonObject = new JSONObject();
					jsonObject.put("addr",area);
					if(only.equals("是")){
						AreaInfo province = areaInfoService.getProvinceByCityName(area);
						if(province == null){
							errorMessage = String.format("未找到市区\"%s\"，请确定市区名字是否正确",area);
							result.setStatus(false);
							result.setMsg(errorMessage);
							return result;
						}
						String parent = province.getName();
						jsonObject.put("parent",parent);
					}else{
						AreaInfo province = areaInfoService.getProvinceByName(area);
						if(province == null){
							errorMessage = String.format("未找到省\"%s\"",area);
							result.setStatus(false);
							result.setMsg(errorMessage);
							return result;
						}
					}
					jsonObject.put("no",no);
					jsonArray.add(jsonObject);
					items.add(area);
					++no;
				}
				am.setItems(JSONObject.toJSONString(items));
				am.setItemsDatail(jsonArray.toJSONString());
				lists.add(am);
			}
			result.setStatus(true);
			result.setMsg("导入成功");
			result.setData(lists);
		} catch (Exception e) {
			logger.error("addressMappingImport.error", e);
			result.setMsg(errorMessage);
		}
		return result;
	}

	/**
	 * 映射地区模板下载
	 */
	@RequestMapping("/downloadAddressMappingTemplate")
	public String downloadAdjustAccTemplate(HttpServletRequest request, HttpServletResponse response) {
		String filePath = request.getServletContext().getRealPath("/") + File.separator + "template" + File.separator + "addressMappingTemplate1.xlsx";
		ResponseUtil.download(response, filePath, "映射地区模板.xlsx");
		return null;
	}


	@RequestMapping("/beforeWarningTemplate")
	@ResponseBody
	public Result beforeWarningTemplate(){
		Result result = new Result();
		List<JumpWarn> jumpWarns = jumpWarnService.select();
		List<WarningConfigTemplate> warningConfigTemplates = jumpRouteSevice.warningConfigTemplateList();
		Map<String,Object> map = new HashMap<>();
		map.put("templates",warningConfigTemplates);
		map.put("jumpWarns",jumpWarns);
		result.setData(map);
		result.setStatus(true);
		return result;
	}

	@SystemLog(description = "核心交易预警",operCode="warningTemplate.update")
	@RequestMapping("/updateBeforeWarningTemplate")
	@ResponseBody
	public Result updateBeforeWarningTemplate(@RequestBody String params){
		JSONObject jsonObject = JSONObject.parseObject(params);
		Result result = new Result();

		JSONArray msgReceiver = jsonObject.getJSONArray("msgReceiver");
		JSONArray beforeGroup = jsonObject.getJSONArray("beforeGroup");

		if(CollectionUtil.isNotEmpty(msgReceiver)){
			for (Object o : msgReceiver) {
				JSONObject object = (JSONObject) o;
				Integer type = object.getInteger("type");
				String msg = object.getString("msg");
				jumpRouteSevice.updateWarningConfigTemplate(type,msg);
			}
		}

		List<JumpWarn> list = new ArrayList<>();
		if(CollectionUtil.isNotEmpty(beforeGroup)){
			for (Object o : beforeGroup) {
				JSONObject object = (JSONObject) o;
//				JumpWarn jumpWarn1 = object.toJavaObject(JumpWarn.class);
				String jsonString = object.toJSONString();
				JumpWarn jumpWarn = JSONObject.parseObject(jsonString,JumpWarn.class);
				list.add(jumpWarn);
			}
		}
		jumpWarnService.update(list);

		result.setMsg("更新成功");
		result.setStatus(true);
		return result;
	}


	/**
	 * 修改交易跳转集群配置状态
	 *
	 * @param params
	 * @return
	 */
	@RequestMapping(value = "/updateJumpRouteStatus.do")
	@ResponseBody
	@SystemLog(description = "修改交易跳转集群配置状态", operCode = "jumpRoute.switchStatus")
	public Result updateJumpRouteStatus(@RequestBody String params) {
		Result result = Result.fail();
		try {
			JSONObject json = JSON.parseObject(params);
			Integer id = json.getInteger("id");
			Boolean statusBoolean = json.getBooleanValue("status");
			Integer status = statusBoolean ? 1 : 0;
			final UserLoginInfo principal = (UserLoginInfo) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			String mender = principal.getUsername();
			int num = jumpRouteSevice.updateStatus(id, status, mender);
			if (num == 1) {
				result = Result.success();
			}
		} catch (Exception e) {
			logger.error("修改交易跳转集群配置状态", e);
			result = ResponseUtil.buildResult(e);
		}
		return result;
	}


	//映射地区导出
	@DataSource(Constants.DATA_SOURCE_SLAVE)
	@RequestMapping("/addressMappingExport.do")
	public void addressMappingExport(Integer id,HttpServletResponse response){
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss") ;
			OutputStream ouputStream = null;
			try {
				List<AddressMapping> list = addressMappingService.list(id);
				int size = 2;
				ListDataExcelExport export = new ListDataExcelExport(size);
				String fileName = "映射地区" + sdf.format(new Date()) + export.getFileSuffix(size);
				String fileNameFormat = new String(fileName.getBytes(),"ISO-8859-1");
				response.setHeader("Content-disposition", "attachment;filename="+fileNameFormat);
				response.setContentType("application/vnd.ms-excel;charset=utf-8");
				List<Map<String, String>> data = new ArrayList<>();

				List<String> colsList = new ArrayList<>(Arrays.asList("registerAddress","registerAddressType","join"));
				List<String> colsNameList = new ArrayList<>(Arrays.asList("商户注册地","是否单列市","不参与地区集群轮循"));

				int maxLength = 0;
				if(CollectionUtil.isNotEmpty(list)){
					for (AddressMapping addressMapping : list) {
						Map<String,String> map = new HashMap<>();
						map.put("registerAddress",addressMapping.getRegisterAddress());
						String registerAddressType = addressMapping.getRegisterAddressType() == 1 ? "是" : "否";
						map.put("registerAddressType",registerAddressType);
						String join = addressMapping.getJoinAreaPolling() == 1 ? "不参与" : "参与";
						map.put("join",join);

						String itemsDatail = addressMapping.getItemsDatail();
						JSONArray jsonArray = JSONArray.parseArray(itemsDatail);

						List<JSONObject> jsonObjectList = JSONArray.parseArray(jsonArray.toJSONString(), JSONObject.class);
						int length = jsonObjectList.size();
						if(length > maxLength){
							maxLength = length;
						}

						Collections.sort(jsonObjectList, new Comparator<JSONObject>() {
							@Override
							public int compare(JSONObject o1, JSONObject o2) {
								int a = o1.getInteger("no");
								int b = o2.getInteger("no");
								if (a < b) {
									return -1;
								} else if(a == b) {
									return 0;
								} else
									return 1;
							}
						});

						if(jsonObjectList.size() > 0){
							int i = 0;
							for (JSONObject jsonObject : jsonObjectList) {
								++i;
								String addr = jsonObject.getString("addr");
								String parent = jsonObject.getString("parent");
								String onlyCity = StrUtil.isNotBlank(parent) ? "是" : "否";
								map.put("mapping"+i,addr);
								map.put("onlyCity"+i,onlyCity);
							}
						}
						data.add(map);
					}
				}

				for (int i = 0; i < maxLength; i++) {
					colsList.add("mapping"+(i+1));
					colsList.add("onlyCity"+(i+1));
					colsNameList.add("映射"+(i+1));
					colsNameList.add("是否单列市");
				}

				String[] cols = new String[colsList.size()];
				colsList.toArray(cols);

				String[] colsName = new String[colsNameList.size()];
				colsNameList.toArray(colsName);

				ouputStream = response.getOutputStream();
				export.export(cols, colsName, data, response.getOutputStream());
			} catch (Exception e) {
				logger.error("映射地区导出导出异常", e);
			} finally {
				if(ouputStream!=null){
					try {
						ouputStream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		} catch (Exception e){
			logger.error("映射地区导出导出异常", e);
		}
	}

	//账单地预留额度监控查询
	@RequestMapping("/accountAddressQuotaMonitor.do")
	@ResponseBody
	public Page<AccountAddress> accountAddressQuotaMonitor(String address,Integer addressType,String dateStart,String dateEnd,@ModelAttribute("page") Page<AccountAddress> page){
		try {
			List<AccountAddress> accountAddressList = accountAddressService.findAccountAddressByDateAndAccountAddressAndType(dateStart, dateEnd, address, addressType, page);
			page.setResult(accountAddressList);
			return page;
		} catch (Exception e) {
			logger.error("查询智能路由交易监控数据异常", e);
		}
		return null;
	}

	//账单地预留额度监控详情
	@RequestMapping("/accountAddressQuotaMonitorExport.do")
	@SystemLog(operCode = "accountAddressQuotaMonitorExport.export", description = "账单地预留额度监控导出")
	public void accountAddressQuotaMonitorExport(String address,Integer addressType,String dateStart,String dateEnd, HttpServletResponse response){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss") ;
		OutputStream ouputStream = null;
		try {
			Page<AccountAddress> page = new Page<>(1,Integer.MAX_VALUE);
			List<AccountAddress> accountAddressList = accountAddressService.findAccountAddressByDateAndAccountAddressAndType(dateStart, dateEnd, address, addressType, page);
			int size = 2;
			ListDataExcelExport export = new ListDataExcelExport(size);
			String fileName = "账单地预留额度" +sdf.format(new Date())+ export.getFileSuffix(size);
			String fileNameFormat = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
			response.setHeader("Content-disposition", "attachment;filename=" + fileNameFormat);
			response.setContentType("application/vnd.ms-excel;charset=utf-8");

			List<Map<String,String>> list = new ArrayList<>();

			if(CollectionUtil.isNotEmpty(accountAddressList)){
				for (AccountAddress accountAddress : accountAddressList) {
					Map<String,String> map = new HashMap<>();
					map.put("address",accountAddress.getAddress());
					String addressTypeStr = accountAddress.getAddressType() == 1 ? "是" : "否";
					map.put("addressType",addressTypeStr);
					map.put("releaseTime",DateUtil.formatTime(accountAddress.getReleaseTime()));
					map.put("reservedAmount",accountAddress.getReservedAmount().toString());
					map.put("localUsed",accountAddress.getLocalUsed().toString());
					map.put("otherUsed",accountAddress.getOtherUsed().toString());
					map.put("accountDate",DateUtil.formatDate(accountAddress.getAccountDate()));
					list.add(map);
				}
			}

			String[] cols = new String[]{
					"address","addressType","releaseTime","reservedAmount","localUsed","otherUsed","accountDate"
			};
			String[] colsName = new String[]{
					"账单地","是否单列市","释放时间点","预留额度","账单地已用额度","其他地区已用额度","日期"
			};

			ouputStream = response.getOutputStream();

			export.export(cols, colsName, list, response.getOutputStream());
		} catch (Exception e) {
			logger.error("账单地监控详情导出异常", e);
		} finally {
			try {
				if (ouputStream != null) {
					ouputStream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
